﻿using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
//using OmegaEngine;

namespace OmegaEngine
{
    public class Actor : Component, I3DComponent
    {
        // The model to draw
        Model model;

        // Network priority
        float NetPriority = 1.0f;

        // I3DComponent values
        public virtual Vector3 Position { get; set; }
        public Vector3 EulerRotation
        {
            get { return MathUtil.MatrixToVector3(Rotation); }
            set { Rotation = MathUtil.Vector3ToMatrix(value); }
        }
        public virtual Matrix Rotation { get; set; }
        public virtual Vector3 Scale { get; set; }
        public virtual BoundingBox BoundingBox
        {
            get
            {
                return new BoundingBox
                (
                    Position - (Scale / 2),
                    Position + (Scale / 2)
                );
            }
        }

        // Constructors take a model to draw and a position
        public Actor(Model Model, Vector3 Position) : base()
        {
            Setup(Model, Position);
        }

        public Actor(Model Model, Vector3 Position, GameScreen Parent) : base(Parent)
        {
            Setup(Model, Position);
        }

        // Provide a method to setup the actor so we don't need to
        // write it in each constructor
        void Setup(Model Model, Vector3 Position)
        {
            this.model = Model;
            this.Position = Position;
            Scale = Vector3.One;
            EulerRotation = Vector3.Zero;
        }

        public override void Draw()
        {
            // Look for a camera in the service container
            Camera camera = Engine.Services.GetService<Camera>();

            // Throw an exception if one isn't present
            if (camera == null)
            {
                throw new Exception("Camera not found in engine's service container, cannot draw");
            }

            // Generate the world matrix (describes the objects movement in 3D)
            Matrix world = MathUtil.CreateWorldMatrix(Position, Rotation, Scale);

            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            // Set some renderstates so the model will draw properly
            Engine.GraphicsDevice.BlendState = BlendState.AlphaBlend;
            Engine.GraphicsDevice.DepthStencilState = DepthStencilState.Default; // DepthRead
            //Engine.GraphicsDevice.RenderState.AlphaBlendEnable = true;
            //Engine.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
            //Engine.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
            //Engine.GraphicsDevice.RenderState.DepthBufferEnable = true;
            //Engine.GraphicsDevice.RenderState.
            // TODO: WHAT

            // Loop through meshes and effects and set them up to draw
            foreach (ModelMesh mesh in model.Meshes)
            {
                /*foreach (BasicEffect effect in mesh.Effects)
                {
                    // Set effect parameters
                    effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * world);
                    effect.Parameters["View"].SetValue(camera.View);
                    effect.Parameters["Projection"].SetValue(camera.Projection);

                    // Enable lighting
                    effect.EnableDefaultLighting();
                }*/

                // Draw the mesh
                mesh.Draw();
            }
        }
    }
}